<?php
/**
 ***********************************************************************************************************************
 * 日志处理类
 ***********************************************************************************************************************
 */

namespace artisan\logger;

/**
 * Class logger
 * @package artisan\logger
 */
class logger
{
    /**
     * Detailed debug information
     */
    const DEBUG = 'DEBUG';

    /**
     * Interesting events
     *
     * Examples: User logs in, SQL logs.
     */
    const INFO = 'INFO';

    /**
     * Uncommon events
     */
    const NOTICE = 'NOTICE';

    /**
     * Exceptional occurrences that are not errors
     *
     * Examples: Use of deprecated APIs, poor use of an API,
     * undesirable things that are not necessarily wrong.
     */
    const WARNING = 'WARNING';

    /**
     * Runtime errors
     */
    const ERROR = 'ERROR';

    /**
     * Critical conditions
     *
     * Example: Application component unavailable, unexpected exception.
     */
    const CRITICAL = 'CRITICAL';

    /**
     * Action must be taken immediately
     *
     * Example: Entire website down, database unavailable, etc.
     * This should trigger the SMS alerts and wake you up.
     */
    const ALERT = 'ALERT';

    /**
     * Urgent alert.
     */
    const EMERGENCY = 'EMERGENCY';

    /**
     * @var array
     */
    private static $levelMap = array(
        'DEBUG'     => 0,
        'INFO'      => 1,
        'NOTICE'    => 2,
        'WARNING'   => 3,
        'ERROR'     => 4,
        'CRITICAL'  => 5,
        'ALERT'     => 6,
        'EMERGENCY' => 7,
    );

    /**
     * @var storage\file|storage\syslog
     */
    private static $handler;


    /**
     * @param $level
     * @param $message
     * @param array $context
     * @param string $breakpoint
     * @param string $service_name
     * @return bool
     */
    public static function add($level, $message, array $context = array(), $breakpoint = '', $service_name = '',$isRecordAll=false)
    {
        $isRecordAll=$isRecordAll?true:(true===$service_name?true:false);
        $logLevel = (int)globalConfig('log.level');
        // 设为负数即可关闭日志记录
        if($logLevel < 0) {
            return true;
        }
        // DEBUG级别忽视用户设定，永远都记录
        if(self::$levelMap[$level] >= $logLevel || $level === self::DEBUG) {
            $log = array(
                'message' => self::format($message),
                'context' => $context,
                'level' => $level,
                'channel' => project(),
                'datetime' => date('Y-m-d H:i:s'),
                'service_name' => $service_name,
                'breakpoint' => $breakpoint,
                'isRecordAll' => $isRecordAll
            );
            return self::getHandler()->write($log);
        }
        return false;
    }

    /**
     * @param $log
     * @return mixed|string
     */
    public static function format($log)
    {
        if(is_string($log) || is_numeric($log)) {
            return $log;
        }
        if(!is_array($log)) {
            $log = (array)$log;
        }
        return json_encode($log, JSON_UNESCAPED_UNICODE);
    }

    /**
     * 尝试寻找用户自定义日志处理
     *
     * @return storage\file|storage\syslog
     */
    private static function getHandler()
    {
        if(self::$handler === null) {
            $customHandler = globalConfig('log.handler');
            self::$handler = !empty($customHandler) ? new $customHandler : (stripos(PHP_OS, 'win') !== false ? new storage\file() : new storage\syslog());
        }
        return self::$handler;
    }
}